package com.eneat.smartrule;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.core.converter.AnnotatedType;
import io.swagger.v3.core.util.Json;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.headers.Header;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.media.Content;
import io.swagger.v3.oas.models.media.MediaType;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.media.StringSchema;
import io.swagger.v3.oas.models.responses.ApiResponse;
import io.swagger.v3.oas.models.responses.ApiResponses;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import io.swagger.v3.oas.models.servers.Server;
import org.springdoc.core.customizers.GlobalOpenApiCustomizer;
import org.springdoc.core.customizers.PropertyCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Configuration
public class SwaggerConfiguration {

    // 暂时可以不加认证鉴权
    @Bean
    public OpenAPI customOpenAPI() {
//        String securitySchemeName="Authorization";
        return new OpenAPI()
                .addServersItem(new Server().url("/"))
                .addServersItem(new Server().url("https://127.0.0.1:12345/"))
                .components(new Components()
//                        .addHeaders("Authorization", new Header().description("Auth header").schema(new StringSchema()._default("")))
//                        .addSecuritySchemes(securitySchemeName,
//                                new SecurityScheme()
//                                        .type(SecurityScheme.Type.HTTP)
//                                        .scheme("bearer")
//                                        .bearerFormat("JWT")
//                        )
                )
//                .security(List.of(new SecurityRequirement().addList(securitySchemeName)))
                .info(new Info().title("AI API").version("V1"))
                ;
    }

    @Bean
    public GlobalOpenApiCustomizer customerGlobalHeaderOpenApiCustomizer() {
        return openApi ->
                openApi.getPaths().values().forEach(pathItem -> pathItem.readOperations().forEach(operation -> {
                    ApiResponses apiResponses = operation.getResponses();
                    ApiResponse badRequest = new ApiResponse().description("参数错误")
                            .content(new Content()
                                    .addMediaType(org.springframework.http.MediaType.APPLICATION_JSON_VALUE, new MediaType().schema(
                                            new Schema()
                                    )));
                    apiResponses.addApiResponse("400", badRequest);
                    ApiResponse unAuthorization = new ApiResponse().description("未认证")
                            .content(new Content()
                                    .addMediaType(org.springframework.http.MediaType.APPLICATION_JSON_VALUE, new MediaType().schema(
                                            new Schema()
                                    )));
                    apiResponses.addApiResponse("401", unAuthorization);
                    ApiResponse internalError = new ApiResponse().description("内部错误")
                            .content(new Content()
                                    .addMediaType(org.springframework.http.MediaType.APPLICATION_JSON_VALUE, new MediaType().schema(
                                            new Schema()
                                    )));
                    apiResponses.addApiResponse("500", internalError);
                }));
    }
    @Bean
    public PropertyCustomizer EnumValuePropertyCustomizer(){
        return ( property,  type)->{
            if (property instanceof StringSchema && isEnumType(type)) {
                ObjectMapper objectMapper = Json.mapper();

                property.setEnum(Arrays.stream(((JavaType) type.getType()).getRawClass().getEnumConstants())
                        .map(e -> objectMapper.convertValue(e, String.class))
                        .collect(Collectors.toList()));
                // 暂时注释掉描述
//                String description = Arrays.stream(((JavaType) type.getType()).getRawClass().getEnumConstants())
//                        .map(e -> {
//                            Enum en = ((Enum) e);
//                            if (en instanceof Describable) {
//                                return " * `" + en.name() + "` - " + ((Describable) en).getDescription();
//                            }
//                            return null;
//                        })
//                        .filter(Objects::nonNull)
//                        .collect(Collectors.joining("\n"));
//
//                if ( StringUtils.isNotBlank(description)) {
//                    property.setDescription(property.getDescription() + "\n" + description);
//                }
            }
            return property;
        };
    }

    private static boolean isEnumType( AnnotatedType type) {
        return type.getType() instanceof JavaType && ((JavaType) type.getType()).isEnumType();
    }
}